﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Text;
using System.Windows.Forms;
using Components;
using System.Threading;

namespace UI.CommonForm
{
    public partial class FrmWaitingBox : Form
    {
        #region Properties
        private int _MaxWaitTime;
        private int _WaitTime;
        private bool _CancelEnable;
        private IAsyncResult _AsyncResult;
        public delegate string MethodDelge();
        private MethodDelge _Method;
        private bool isComplete = false;
        private bool isOnlyLoading = false; //是否仅仅只是等待加载，不需要检测后台的处理方法的返回值
        private System.Timers.Timer tmClose = null; //等待页面关闭的定时器
        private bool isTicked = false; //实现SetTimeOut的功能，标识定时器是否已经触发过了
        private string defaultMsg = "数据保存成功！";
        private bool isAutoClose = false; //是否自动关闭提示窗口

        /// <summary>
        /// 控制界面显示的特性
        /// </summary>
        public string Message { get; private set; }
        public int TimeSpan { get; set; }
        public bool FormEffectEnable { get; set; }
        #endregion

        #region frmWaitingBox
        public FrmWaitingBox(MethodDelge method, int maxWaitTime, bool cancelEnable, bool timerVisable)
        {
            maxWaitTime *= 1000;
            string waitMessage = "正在处理数据，请稍后...";
            Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
        }
        public FrmWaitingBox(MethodDelge method)
        {
            int maxWaitTime = 60 * 1000;
            string waitMessage = "正在处理数据，请稍后...";
            bool cancelEnable = true;
            bool timerVisable = true;
            Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
        }
        public FrmWaitingBox(MethodDelge method, string waitMessage)
        {
            int maxWaitTime = 60 * 1000;
            bool cancelEnable = true;
            bool timerVisable = true;
            Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
        }
        public FrmWaitingBox(MethodDelge method, bool cancelEnable, bool timerVisable)
        {
            int maxWaitTime = 60 * 1000;
            string waitMessage = "正在处理数据，请稍后...";
            Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
        }
        #endregion

        #region Initialize
        private void Initialize(MethodDelge method, int maxWaitTime, string waitMessage, bool cancelEnable, bool timerVisable)
        {
            InitializeComponent();
            //initialize form
            this.FormBorderStyle = FormBorderStyle.None;
            this.StartPosition = FormStartPosition.CenterParent;
            this.ShowInTaskbar = false;
            this.labMessage.Text = waitMessage;

            //Panel切换
            panError.Visible = false;
            panLoading.Visible = true;

            TimeSpan = 500;
            Message = string.Empty;
            _CancelEnable = cancelEnable;
            _MaxWaitTime = maxWaitTime;
            _WaitTime = 0;
            _Method = method;
            this.pictureBoxCancel.Visible = false;
            this.timer1.Interval = TimeSpan;
            this.timer1.Start();
        }
        #endregion

        #region Events
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Message = "您结束了当前操作！";
            this.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            _WaitTime += TimeSpan;
            if (!this._AsyncResult.IsCompleted)
            {
                if (_WaitTime > _MaxWaitTime)
                {
                    timer1.Stop();

                    ShowMsg(false, string.Format("！处理数据超时{0}秒，结束当前操作", _MaxWaitTime / 1000));//显示消息
                    ShowWaitClosePanel(false);
                }
            }
            else if (!isComplete && this._AsyncResult.IsCompleted &&
                !this._AsyncResult.AsyncWaitHandle.SafeWaitHandle.IsClosed)
            {
                timer1.Stop();
                isComplete = true;
                if (!isOnlyLoading) //如果不是仅为等待页面，需要监控后台返回值
                {
                    string k = _Method.EndInvoke(_AsyncResult); //验证保存数据是否OK
                    bool issuccess = string.IsNullOrEmpty(k); //保存是否成功

                    ShowMsg(issuccess, k);//显示消息

                    ShowWaitClosePanel(issuccess);
                }
                else
                {
                    this.Message = string.Empty;
                    this.Close();
                }
            }

        }

        /// <summary>
        /// 显示等待关闭面板
        /// </summary>
        /// <param name="issuccess"></param>
        private void ShowWaitClosePanel(bool issuccess)
        {
            if (isAutoClose && !issuccess)
            {
                tmClose = new System.Timers.Timer(1000);
                tmClose.Start();

                //只让定时器执行一遍
                tmClose.Elapsed += new System.Timers.ElapsedEventHandler(delegate
                {
                    if (!isTicked)
                    {
                        isTicked = true;
                        return;
                    }

                    this.Close();
                });
            }
        }

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="issuccess"></param>
        /// <param name="msg"></param>
        private void ShowMsg(bool issuccess, string msg)
        {
            this.panLoading.Visible = false;
            panError.Visible = true;
            this.Controls.Add(this.panError);
            this.panError.Dock = DockStyle.Fill;
            this.PicIco.Image = this.imgIco.Images[issuccess ? 0 : 1];

            PicIco.Update();
            lbStatueP1.Text = issuccess ? defaultMsg : msg;
            lbStatueP1.ForeColor = issuccess ? Color.Black : Color.Red;
            lbStatueP1.Update();
            this.panError.Update();
        }

        private void frmWaitingBox_Shown(object sender, EventArgs e)
        {
            _AsyncResult = _Method.BeginInvoke(null, null);
        }

        private void frmWaitingBox_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private string ChancleMethod() { return ""; }

        #endregion

        private void picExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
